package org.swingplus.core.scanner;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.swingplus.core.annotation.Order;
import org.swingplus.core.context.ApplicationContext;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

public class OrderScan extends ComponentScan {
    private static final Logger logger = LoggerFactory.getLogger(OrderScan.class);

    public static void orderScan(List<Object> objs) throws Exception {
        for (int i = 0; i < objs.size(); i++) {
            Object obj = objs.get(i);
            orderScan(obj);
        }

    }

    public static void orderScan(Object instance) throws Exception {
        if (null == instance) {
            throw new NullPointerException("orderScan instance is null");
        }
        Method[] thisMethodBySortAsc = null;
        //默认级别为0的默认最后执行
        List<Method> methodDefaultList = new ArrayList<>();
        Map<String, Method> methodOrderMap = new HashMap<>();
//		Method[] thisMethod=null;
        Method[] declaredMethods = instance.getClass().getDeclaredMethods();
        for (Method method : declaredMethods) {
            Order orderAnn = method.getAnnotation(Order.class);
            if (null == orderAnn) {
                continue;
            }
            String tag = orderAnn.tag();
            //对当前类的执行方法运行前编排
            if ("this".equals(tag) || "".equals(tag)) {
                int value = orderAnn.value();
                if (value == 0) {
                    methodDefaultList.add(method);
                } else {
                    if (methodOrderMap.containsKey(String.valueOf(value))) {
                        throw new Exception("the same as excution order,no must");
                    } else {
                        methodOrderMap.put(String.valueOf(value), method);
                    }
                }


//					for (Map.Entry<String, Method> entry : methodOrderMap.entrySet()) {
//						System.out.println(entry.getKey() + " " + entry.getValue().getName());
//					}
            } else {
                //不是本类中的order tag执行顺序方法栈目前有问题Error

                //如果是成员变量上的执行方法
                Field[] fields = instance.getClass().getFields();
                boolean isSelfExists = false;
                for (Field field : fields) {
                    if (tag.equals(field.getName())) {
                        isSelfExists = true;
                    }
                    //TODO 本类中成员变量中order执行的方法
                }


                //order中声明的tag未指向本类中的成员变量,在容器中寻找变量
                if (!isSelfExists) {
                    Object obj = ApplicationContext.getBean(tag);
                    method.invoke(obj);
                }
            }


        }
        //对map利用key排序
        methodOrderMap = sortMapByKey(methodOrderMap);
        int length = methodDefaultList.size();
        if (null != methodOrderMap) {
            length += methodOrderMap.size();
        }

        if (length > 0) {
            thisMethodBySortAsc = new Method[length];
            if (null != methodOrderMap) {
                for (int i = 0; i < methodOrderMap.size(); i++) {
                    thisMethodBySortAsc[i] = methodOrderMap.get(String.valueOf(i + 1));
                }
            }
            for (int i = 0; i < methodDefaultList.size(); i++) {
                thisMethodBySortAsc[methodOrderMap.size() + i] = methodDefaultList.get(i);
            }
            //依次执行编排后的方法
            for (Method method2 : thisMethodBySortAsc) {
                method2.setAccessible(true);
                method2.invoke(instance);
                method2.setAccessible(false);
            }
        } else {
            if (logger.isDebugEnabled()) {
                logger.info("current bean: {} no declaration {} Annotation", instance, Order.class);
            }
        }
    }

    /**
     * 让 Map按key进行排序
     */
    public static Map<String, Method> sortMapByKey(Map<String, Method> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Map<String, Method> sortMap = new TreeMap<String, Method>(new MapKeyComparator());
        sortMap.putAll(map);
        return sortMap;
    }
}

class MapKeyComparator implements Comparator<String> {

    @Override
    public int compare(String s1, String s2) {
        return s1.compareTo(s2);  //从小到大排序
    }
}

	



